package com.bicon.botu.file.upload.common;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by lenovo on 2016/6/28.
 */
@Slf4j
public class FileUtils {

    /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dir
     *            要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator)) {
            dir = dir + File.separator;
        }
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i]
                        .getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }


    public static void fileMove(String from, String to) throws Exception {// 移动指定文件夹内的全部文件
        try {
            File dir = new File(from);
            File[] files = dir.listFiles();// 将文件或文件夹放入文件集
            if (files == null)// 判断文件集是否为空
            {
                return;
            }
            File moveDir = new File(to);// 创建目标目录
            if (!moveDir.exists()) {// 判断目标目录是否存在
                moveDir.mkdirs();// 不存在则创建
            }
            for (int i = 0; i < files.length; i++) {// 遍历文件集
                if (files[i].isDirectory()) {// 如果是文件夹或目录,则递归调用fileMove方法，直到获得目录下的文件
                    fileMove(files[i].getPath(), to + "\\" + files[i].getName());// 递归移动文件
                    files[i].delete();// 删除文件所在原目录
                }
                File moveFile = new File(moveDir.getPath() + "\\"// 将文件目录放入移动后的目录
                        + files[i].getName());
                if (moveFile.exists()) {// 目标文件夹下存在的话，删除
                    moveFile.delete();
                }
                files[i].renameTo(moveFile);// 移动文件
                log.debug(files[i] + " 移动成功");
            }
        } catch (Exception e) {
            throw e;
        }
    }



    /**
     *  复制单个文件
     *  @param  oldPath  String  原文件路径  如：c:/fqf.txt
     *  @param  newPath  String  复制后路径  如：f:/fqf.txt
     *  @return  boolean
     */
    public static void copyFile(String oldPath,String newPath) {// 复制文件
        File toFile = new File(newPath);
        File fromFile = new File(oldPath);
        if (toFile.exists()) {// 判断目标目录中文件是否存在
            log.debug("文件" + toFile.getAbsolutePath() + "已经存在，跳过该文件！");
            return;
        } else {
            createFile(toFile, true);// 创建文件
        }
        log.debug("复制文件" + fromFile.getAbsolutePath() + "到"
                + toFile.getAbsolutePath());
        try {
            InputStream is = new FileInputStream(fromFile);// 创建文件输入流
            FileOutputStream fos = new FileOutputStream(toFile);// 文件输出流
            byte[] buffer = new byte[1024];// 字节数组
            while (is.read(buffer) != -1) {// 将文件内容写到文件中
                fos.write(buffer);
            }
            is.close();// 输入流关闭
            fos.close();// 输出流关闭
        } catch (FileNotFoundException e) {// 捕获文件不存在异常
            e.printStackTrace();
        } catch (IOException e) {// 捕获异常
            e.printStackTrace();
        }
    }

    /**
     *  复制整个文件夹内容
     *  @param  oldPath  String  原文件路径  如：c:/fqf
     *  @param  newPath  String  复制后路径  如：f:/fqf/ff
     *  @return  boolean
     */
    public static void copyFolder(String  oldPath,  String  newPath)  {

        try  {
            (new  File(newPath)).mkdirs();  //如果文件夹不存在  则建立新文件夹
            File  a=new  File(oldPath);
            String[]  file=a.list();
            File  temp=null;
            for  (int  i  =  0;  i  <  file.length;  i++)  {
                if(oldPath.endsWith(File.separator)){
                    temp=new  File(oldPath+file[i]);
                }
                else{
                    temp=new  File(oldPath+File.separator+file[i]);
                }

                if(temp.isFile()){
                    FileInputStream  input  =  new  FileInputStream(temp);
                    FileOutputStream  output  =  new  FileOutputStream(newPath  +  "/"  +
                            (temp.getName()).toString());
                    byte[]  b  =  new  byte[1024  *  5];
                    int  len;
                    while  (  (len  =  input.read(b))  !=  -1)  {
                        output.write(b,  0,  len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if(temp.isDirectory()){//如果是子文件夹
                    copyFolder(oldPath+"/"+file[i],newPath+"/"+file[i]);
                }
            }
        }
        catch  (Exception  e)  {
            e.printStackTrace();
        }

    }

    public static void createFile(File file, boolean isFile) {// 创建文件
        if (!file.exists()) {// 如果文件不存在
            if (!file.getParentFile().exists()) {// 如果文件父目录不存在
                createFile(file.getParentFile(), false);
            } else {// 存在文件父目录
                if (isFile) {// 创建文件
                    try {
                        file.createNewFile();// 创建新文件
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    file.mkdir();// 创建目录
                }
            }
        }
    }

    public static void createFolder(File file) {// 创建文件夹
        if (!file.exists()) {
            file.mkdirs();
        }
    }


    public static String getPrefix(String fileName){
        String prefix=fileName.substring(fileName.lastIndexOf(".")+1);
        return prefix;
    }


    /**
     * 文件大小转换
     * @param size
     * @return
     */
    public static String convertFileSize(long size) {
        long kb = 1024;
        long mb = kb * 1024;
        long gb = mb * 1024;

        if (size >= gb) {
            return String.format("%.1fGB", (float) size / gb);
        } else if (size >= mb) {
            float f = (float) size / mb;
            return String.format(f > 100 ? "%.0fMB" : "%.1f MB", f);
        } else if (size >= kb) {
            float f = (float) size / kb;
            return String.format(f > 100 ? "%.0fKB" : "%.1f KB", f);
        } else {
            return String.format("%dB", size);
        }
    }

    /**
     * 计算文件或者文件夹的大小 ，单位 MB
     * @param file 要计算的文件或者文件夹 ， 类型：java.io.File
     * @return 大小，单位：MB
     */
    public static long getSize(File file) {
        //判断文件是否存在
        if (file.exists()) {
            //如果是目录则递归计算其内容的总大小，如果是文件则直接返回其大小
            if (!file.isFile()) {
                //获取文件大小
                File[] fl = file.listFiles();
                long ss = 0;
                for (File f : fl)
                    ss += getSize(f);
                return ss;
            }else{
                return file.length();
            }
        } else {
            return 0;
        }
    }

    /**
     * 文件类型判断
     */

    public Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();

    public String getFileTypeByStream(byte[] b) {
        String filetypeHex = String.valueOf(getFileHexString(b));
        log.debug(filetypeHex);
        Iterator<Map.Entry<String, String>> entryiterator = FILE_TYPE_MAP
                .entrySet().iterator();
        while (entryiterator.hasNext()) {
            Map.Entry<String, String> entry = entryiterator.next();
            String fileTypeHexValue = entry.getValue().toUpperCase();
            if (filetypeHex.toUpperCase().startsWith(fileTypeHexValue)) {
                return entry.getKey();
            }
        }
        return null;
    }

    public String getFileHexString(byte[] b) {
        StringBuilder stringBuilder = new StringBuilder();
        if (b == null || b.length <= 0) {
            return null;
        }
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public void getVideoFileType() {
        FILE_TYPE_MAP.put("ram", "2E7261FD"); // Real Audio (ram)
        FILE_TYPE_MAP.put("rm", "2E524D46"); // Real Media (rm)
        FILE_TYPE_MAP.put("mov", "00000014667479707174"); // Quicktime (mov)
        // FILE_TYPE_MAP.put("rmvb", "2e524d46000000120001"); // rmvb
        FILE_TYPE_MAP.put("avi", "41564920");
        FILE_TYPE_MAP.put("avi", "52494646b440c02b4156");
        FILE_TYPE_MAP.put("flv", "464C5601050000000900");
        FILE_TYPE_MAP.put("mp4", "00000020667479706d70");
        FILE_TYPE_MAP.put("wmv", "3026b2758e66CF11a6d9");
        // FILE_TYPE_MAP.put("3gp", "00000014667479703367");
        FILE_TYPE_MAP.put("mkv", "1a45dfa3010000000000");
    }

    public void getPicFileType() {
        FILE_TYPE_MAP.put("jpg", "FFD8FF"); // JPEG (jpg)
        FILE_TYPE_MAP.put("png", "89504E47"); // PNG (png)
        FILE_TYPE_MAP.put("gif", "47494638"); // GIF (gif)
        FILE_TYPE_MAP.put("bmp", "424D"); // Windows Bitmap (bmp)
        FILE_TYPE_MAP.put("png", "89504E470D0a1a0a0000"); // PNG (png)
        FILE_TYPE_MAP.put("bmp", "424d228c010000000000"); // 16色位图(bmp)
        FILE_TYPE_MAP.put("bmp", "424d8240090000000000"); // 24位位图(bmp)
        FILE_TYPE_MAP.put("bmp", "424d8e1b030000000000"); // 256色位图(bmp
    }

    public void getAudioFileType() {
        FILE_TYPE_MAP.put("wav", "57415645"); // Wave (wav)
        FILE_TYPE_MAP.put("mid", "4D546864"); // MIDI (mid)
        FILE_TYPE_MAP.put("mp3", "49443303000000002176");
        FILE_TYPE_MAP.put("wav", "52494646e27807005741");
        FILE_TYPE_MAP.put("aac", "fff1508003fffcda004c");
        FILE_TYPE_MAP.put("wv", "7776706ba22100000704");
        FILE_TYPE_MAP.put("flac", "664c6143800000221200");
    }

}
